package com.ctshk.rpc.ship.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.GlobalConstants;
import com.ctshk.common.enums.SystemError;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.model.PageResponse;
import com.ctshk.common.model.TokenUser;
import com.ctshk.common.utils.DateUtil;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.common.utils.SnowflakeIdWorker;
import com.ctshk.rpc.ship.constant.ProductCenterEnum;
import com.ctshk.rpc.ship.dto.*;
import com.ctshk.rpc.ship.entity.*;
import com.ctshk.rpc.ship.mapper.*;
import com.ctshk.rpc.ship.req.*;
import com.ctshk.rpc.ship.service.IShipProductSaleStrategyService;
import com.ctshk.rpc.system.service.ISysDepartmentService;
import com.ctshk.rpc.system.service.ISysPermissionService;
import com.ctshk.rpc.system.service.ISysUserService;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.text.ParseException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 船票销售加幅策略 服务实现类
 * </p>
 *
 * @author 刘蕾
 * @since 2021-03-10
 */
@DubboService
public class ShipProductSaleStrategyServiceImpl extends ServiceImpl<ShipProductSaleStrategyMapper, ShipProductSaleStrategy> implements IShipProductSaleStrategyService {

    @Autowired
    private ShipProductSaleStrategyMapper shipProductSaleStrategyMapper;

    @Autowired
    private ShipProductReservationSettingsMapper shipProductReservationSettingsMapper;

    @Autowired
    private ShipProductMapper shipProductMapper;

    @Autowired
    private ShipProductSaleStrategyVaildDateMapper shipProductSaleStrategyVaildDateMapper;

    @Autowired
    private ShipProductChannelOfflineMapper shipProductChannelOfflineMapper;

    @Autowired
    private ShipProductChannelOfflineAgentCustomMapper shipProductChannelOfflineAgentCustomMapper;

    @Autowired
    private ShipProductChannelOfflineSelfCustomMapper shipProductChannelOfflineSelfCustomMapper;

    @Autowired
    private ShipProductChannelOnlineSelfPlatformMapper shipProductChannelOnlineSelfPlatformMapper;

    @Autowired
    private ShipProductChannelOnlineThirdPlatformMapper shipProductChannelOnlineThirdPlatformMapper;

    @Autowired
    private ShipProductSaleRecordMapper shipProductSaleRecordMapper;
    //自營禁售
    private static final int SEL_CUSTOM_FORBID = 1;
    //所有部門加幅
    private static final int ALL_DEPT_SALE = 2;
    //指定部门/人员
    private static final int PERSONAL_SALE = 3;

    //自營渠道
    private static final int SEL_CUSTOM = 1;
    //代理商渠道
    private static final int AGENT_CUSTOM = 2;

    //數值
    private static final int AMOUNT = 1;
    //百分比
    private static final int PERCENT = 2;

    @DubboReference
    private ISysUserService iSysUserService;
    @DubboReference
    private ISysDepartmentService departmentService;
    @DubboReference
    private ISysPermissionService sysPermissionService;


    /**
     * 根据产品ID获取加幅数据
     *
     * @param productId
     * @return
     */
    @Override
    public List<ShipProductSaleStrategyDTO> queryByProductId(Long productId) {
        List<ShipProductSaleStrategyDTO> list = new ArrayList<>();
        List<ShipProductSaleStrategy> shipProductSaleStrategies = shipProductSaleStrategyMapper.selectList(
                new QueryWrapper<ShipProductSaleStrategy>().lambda().eq(ShipProductSaleStrategy::getProductId, productId));
        if (CollectionUtils.isEmpty(shipProductSaleStrategies)) {
            return null;
        }
        for (ShipProductSaleStrategy shipProductSaleStrategy : shipProductSaleStrategies) {
            ShipProductSaleStrategyDTO shipProductSaleStrategyDTO = new ShipProductSaleStrategyDTO();
            BeanUtils.copyProperties(shipProductSaleStrategy, shipProductSaleStrategyDTO);
            //策略ID
            Long strategyId = shipProductSaleStrategy.getId();
            //有效期
            List<ShipProductSaleStrategyVaildDate> shipProductSaleStrategyVaildDates = shipProductSaleStrategyVaildDateMapper.selectList(
                    new QueryWrapper<ShipProductSaleStrategyVaildDate>().lambda().eq(ShipProductSaleStrategyVaildDate::getStrategyId, strategyId)
            );
            List<ShipProductSaleStrategyVaildDateDTO> shipProductSaleStrategyVaildDateDTOList = EntityUtil.copyList(shipProductSaleStrategyVaildDates, ShipProductSaleStrategyVaildDateDTO.class);
            shipProductSaleStrategyDTO.setShipProductSaleStrategyVaildDateList(shipProductSaleStrategyVaildDateDTOList);
            //线下自营
            List<ShipProductChannelOffline> shipProductChannelOfflineAgentList = shipProductChannelOfflineMapper.selectList(
                    new QueryWrapper<ShipProductChannelOffline>().lambda().eq(ShipProductChannelOffline::getStrategyId, strategyId)
                            .eq(ShipProductChannelOffline::getChannelType, ShipConstants.OFFLINE_AGENT_CHANNEL_TYPE)
            );
            List<ShipProductChannelOfflineAgentCustomDTO> shipProductChannelOfflineAgentCustomDTOS = EntityUtil.copyList(shipProductChannelOfflineAgentList, ShipProductChannelOfflineAgentCustomDTO.class);
            for (ShipProductChannelOfflineAgentCustomDTO shipProductChannelOfflineAgentCustomDTO : shipProductChannelOfflineAgentCustomDTOS) {
                shipProductChannelOfflineAgentCustomDTO.setShipProductChannelOfflineAgentCustomArray(
                        EntityUtil.copyList(shipProductChannelOfflineAgentCustomMapper.selectList(
                                new QueryWrapper<ShipProductChannelOfflineAgentCustom>().lambda().eq(ShipProductChannelOfflineAgentCustom::getOfflineId, shipProductChannelOfflineAgentCustomDTO.getId())
                        ), ShipProductChannelOfflineAgentCustomArrayDTO.class));
            }
            shipProductSaleStrategyDTO.setShipProductChannelOfflineAgentCustomList(shipProductChannelOfflineAgentCustomDTOS);

            //线下代理
            List<ShipProductChannelOffline> shipProductChannelOfflineSelfList = shipProductChannelOfflineMapper.selectList(
                    new QueryWrapper<ShipProductChannelOffline>().lambda().eq(ShipProductChannelOffline::getStrategyId, strategyId)
                            .eq(ShipProductChannelOffline::getChannelType, ShipConstants.OFFLINE_SELF_CHANNEL_TYPE)
            );
            List<ShipProductChannelOfflineSelfCustomDTO> shipProductChannelOfflineSelfCustomDTOS = EntityUtil.copyList(shipProductChannelOfflineSelfList, ShipProductChannelOfflineSelfCustomDTO.class);
            for (ShipProductChannelOfflineSelfCustomDTO shipProductChannelOfflineSelfCustomDTO : shipProductChannelOfflineSelfCustomDTOS) {
                shipProductChannelOfflineSelfCustomDTO.setShipProductChannelOfflineSelfCustomArray(
                        EntityUtil.copyList(shipProductChannelOfflineSelfCustomMapper.selectList(
                                new QueryWrapper<ShipProductChannelOfflineSelfCustom>().lambda().eq(ShipProductChannelOfflineSelfCustom::getOfflineId, shipProductChannelOfflineSelfCustomDTO.getId())
                        ), ShipProductChannelOfflineSelfCustomArrayDTO.class));
            }
            shipProductSaleStrategyDTO.setShipProductChannelOfflineSelfCustomList(shipProductChannelOfflineSelfCustomDTOS);
            //线上自营
            List<ShipProductChannelOnlineSelfPlatform> shipProductChannelOnlineSelfPlatformList = shipProductChannelOnlineSelfPlatformMapper.selectList(
                    new QueryWrapper<ShipProductChannelOnlineSelfPlatform>().lambda().eq(ShipProductChannelOnlineSelfPlatform::getStrategyId, strategyId)
            );
            shipProductSaleStrategyDTO.setShipProductChannelOnlineSelfPlatformList(
                    EntityUtil.copyList(shipProductChannelOnlineSelfPlatformList, ShipProductChannelOnlineSelfPlatformDTO.class));
            //线上第三方
            List<ShipProductChannelOnlineThirdPlatform> shipProductChannelOnlineThirdPlatforms = shipProductChannelOnlineThirdPlatformMapper.selectList(
                    new QueryWrapper<ShipProductChannelOnlineThirdPlatform>().lambda().eq(ShipProductChannelOnlineThirdPlatform::getStrategyId, strategyId)
            );
            shipProductSaleStrategyDTO.setShipProductChannelOnlineThirdPlatformList(
                    EntityUtil.copyList(shipProductChannelOnlineThirdPlatforms, ShipProductChannelOnlineThirdPlatformDTO.class));
            list.add(shipProductSaleStrategyDTO);
        }

        return list;
    }

    @Override
    public List<ShipProductSaleStrategyDTO> queryByDate(ShipProductSaleStrategyQueryReq queryDateReq) {
        List<ShipProductSaleStrategyDTO> list = new ArrayList<>();
        ShipProductSaleStrategyDTO shipProductSaleStrategyDTO = shipProductSaleStrategyMapper.querySaleStrategy(queryDateReq);

        if(shipProductSaleStrategyDTO == null){
            return Lists.newArrayListWithExpectedSize(1);
        }
        //有效期
        List<ShipProductSaleStrategyVaildDate> shipProductSaleStrategyVaildDates = shipProductSaleStrategyVaildDateMapper.selectList(
                new QueryWrapper<ShipProductSaleStrategyVaildDate>().lambda().eq(ShipProductSaleStrategyVaildDate::getStrategyId,
                        shipProductSaleStrategyDTO.getId())
        );
        List<ShipProductSaleStrategyVaildDateDTO> shipProductSaleStrategyVaildDateDTOList = EntityUtil.copyList(shipProductSaleStrategyVaildDates, ShipProductSaleStrategyVaildDateDTO.class);
        //策略ID
        Long strategyId = shipProductSaleStrategyVaildDateDTOList.get(0).getStrategyId();
        shipProductSaleStrategyDTO.setShipProductSaleStrategyVaildDateList(shipProductSaleStrategyVaildDateDTOList);
        //线下自营
        List<ShipProductChannelOffline> shipProductChannelOfflineAgentList = shipProductChannelOfflineMapper.selectList(
                new QueryWrapper<ShipProductChannelOffline>().lambda().eq(ShipProductChannelOffline::getStrategyId, strategyId)
                        .eq(ShipProductChannelOffline::getChannelType, ShipConstants.OFFLINE_AGENT_CHANNEL_TYPE)
        );
        List<ShipProductChannelOfflineAgentCustomDTO> shipProductChannelOfflineAgentCustomDTOS = EntityUtil.copyList(shipProductChannelOfflineAgentList, ShipProductChannelOfflineAgentCustomDTO.class);
        for (ShipProductChannelOfflineAgentCustomDTO shipProductChannelOfflineAgentCustomDTO : shipProductChannelOfflineAgentCustomDTOS) {
            shipProductChannelOfflineAgentCustomDTO.setShipProductChannelOfflineAgentCustomArray(
                    EntityUtil.copyList(shipProductChannelOfflineAgentCustomMapper.selectList(
                            new QueryWrapper<ShipProductChannelOfflineAgentCustom>().lambda().eq(ShipProductChannelOfflineAgentCustom::getOfflineId, shipProductChannelOfflineAgentCustomDTO.getId())
                    ), ShipProductChannelOfflineAgentCustomArrayDTO.class));
        }
        shipProductSaleStrategyDTO.setShipProductChannelOfflineAgentCustomList(shipProductChannelOfflineAgentCustomDTOS);

        //线下代理
        List<ShipProductChannelOffline> shipProductChannelOfflineSelfList = shipProductChannelOfflineMapper.selectList(
                new QueryWrapper<ShipProductChannelOffline>().lambda().eq(ShipProductChannelOffline::getStrategyId, strategyId)
                        .eq(ShipProductChannelOffline::getChannelType, ShipConstants.OFFLINE_SELF_CHANNEL_TYPE)
        );
        List<ShipProductChannelOfflineSelfCustomDTO> shipProductChannelOfflineSelfCustomDTOS = EntityUtil.copyList(shipProductChannelOfflineSelfList, ShipProductChannelOfflineSelfCustomDTO.class);
        for (ShipProductChannelOfflineSelfCustomDTO shipProductChannelOfflineSelfCustomDTO : shipProductChannelOfflineSelfCustomDTOS) {
            shipProductChannelOfflineSelfCustomDTO.setShipProductChannelOfflineSelfCustomArray(
                    EntityUtil.copyList(shipProductChannelOfflineSelfCustomMapper.selectList(
                            new QueryWrapper<ShipProductChannelOfflineSelfCustom>().lambda().eq(ShipProductChannelOfflineSelfCustom::getOfflineId, shipProductChannelOfflineSelfCustomDTO.getId())
                    ), ShipProductChannelOfflineSelfCustomArrayDTO.class));
        }
        shipProductSaleStrategyDTO.setShipProductChannelOfflineSelfCustomList(shipProductChannelOfflineSelfCustomDTOS);
        //线上自营
        List<ShipProductChannelOnlineSelfPlatform> shipProductChannelOnlineSelfPlatformList = shipProductChannelOnlineSelfPlatformMapper.selectList(
                new QueryWrapper<ShipProductChannelOnlineSelfPlatform>().lambda().eq(ShipProductChannelOnlineSelfPlatform::getStrategyId, strategyId)
        );
        shipProductSaleStrategyDTO.setShipProductChannelOnlineSelfPlatformList(
                EntityUtil.copyList(shipProductChannelOnlineSelfPlatformList, ShipProductChannelOnlineSelfPlatformDTO.class));
        //线上第三方
        List<ShipProductChannelOnlineThirdPlatform> shipProductChannelOnlineThirdPlatforms = shipProductChannelOnlineThirdPlatformMapper.selectList(
                new QueryWrapper<ShipProductChannelOnlineThirdPlatform>().lambda().eq(ShipProductChannelOnlineThirdPlatform::getStrategyId, strategyId)
        );
        shipProductSaleStrategyDTO.setShipProductChannelOnlineThirdPlatformList(
                EntityUtil.copyList(shipProductChannelOnlineThirdPlatforms, ShipProductChannelOnlineThirdPlatformDTO.class));
        list.add(shipProductSaleStrategyDTO);

        return list;
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result setRecommend(ShipProductReq shipProductReq, TokenUser user) {
        ShipProduct shipProduct = shipProductMapper.selectById(shipProductReq.getId());
        shipProduct.setIsRecommend(shipProductReq.getIsRecommend());
        shipProduct.setGmtModified(LocalDateTime.now());
        shipProduct.setModifiedId(user.getId());
        shipProductMapper.updateById(shipProduct);
        return Result.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result putAway(ShipProductBatchSaleStrategyReq localFunProductBatchSaleStrategyReq, TokenUser currentUser) {
        //获取当前用户ID
        Long userId = currentUser == null ? null : currentUser.getId();
        //数据准备
        List<Long> funProductIdList = localFunProductBatchSaleStrategyReq.getLocalFunProductIdList();
        List<ShipProductPutReq> strategyList = localFunProductBatchSaleStrategyReq.getStrategyList();

        //數據校驗
        Result result = checkDataBeforePutAway(localFunProductBatchSaleStrategyReq, funProductIdList, strategyList);
        if (result != null) return result;

        //遍历配置每个产品的增幅策略
        for (Long productId : funProductIdList) {
            //删除历史策略数据
            deleteHistoryStrategyData(productId,localFunProductBatchSaleStrategyReq);

            for (ShipProductPutReq localFunProductSaleStrategyReq : strategyList) {
                //1.新增产品增幅策略
                Long strategyId = addAndUpdateSaleStrategy(userId, productId, localFunProductSaleStrategyReq);

                //2.设置产品增幅策略有效期
                addSaleStrategyValidDate(productId, localFunProductSaleStrategyReq, strategyId);

                //3.设置渠道加幅
                addChannelSale(strategyId,localFunProductSaleStrategyReq,productId,userId);
            }
            ShipProduct shipProduct = shipProductMapper.selectById(productId);
            //已上架
            shipProduct.setShelvesStatus(1);
            shipProductMapper.updateById(shipProduct);
        }
        return Result.success();
    }

    /**
     * 删除历史数据
     * @param productId
     * @param req
     */
    private void deleteHistoryStrategyData(Long productId, ShipProductBatchSaleStrategyReq req) {
        QueryWrapper<ShipProductSaleStrategy> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ShipProductSaleStrategy::getProductId,productId);
        List<ShipProductSaleStrategy> strategies = shipProductSaleStrategyMapper.selectList(queryWrapper);

        for(ShipProductSaleStrategy strategy : strategies){

            shipProductSaleStrategyMapper.deleteById(strategy.getId());
            //删除有效期
            QueryWrapper<ShipProductSaleStrategyVaildDate> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.lambda().eq(ShipProductSaleStrategyVaildDate::getStrategyId,strategy.getId());
            shipProductSaleStrategyVaildDateMapper.delete(queryWrapper1);

            //删除权限
            QueryWrapper<ShipProductChannelOffline> queryWrapper2 = new QueryWrapper<>();
            queryWrapper2.lambda().eq(ShipProductChannelOffline::getStrategyId,strategy.getId());
            shipProductChannelOfflineMapper.delete(queryWrapper2);

            QueryWrapper<ShipProductChannelOffline> queryWrapper3 = new QueryWrapper<>();
            queryWrapper3.lambda().eq(ShipProductChannelOffline::getStrategyId,strategy.getId());
            List<ShipProductChannelOffline> channelOfflines = shipProductChannelOfflineMapper.selectList(queryWrapper3);

            if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(channelOfflines)){
                channelOfflines.forEach(en->{
                    //删除权限
                    shipProductChannelOfflineMapper.deleteById(en.getId());
                    //删除线下自营
                    if(en.getChannelType() ==1){
                        QueryWrapper<ShipProductChannelOfflineSelfCustom> queryWrapper4 = new QueryWrapper<>();
                        queryWrapper4.lambda().eq(ShipProductChannelOfflineSelfCustom::getOfflineId,en.getId());
                        shipProductChannelOfflineSelfCustomMapper.delete(queryWrapper4);
                    }
                    //删除代理商
                    else {
                        QueryWrapper<ShipProductChannelOfflineAgentCustom> queryWrapper5= new QueryWrapper<>();
                        queryWrapper5.lambda().eq(ShipProductChannelOfflineAgentCustom::getOfflineId,en.getId());
                        shipProductChannelOfflineAgentCustomMapper.delete(queryWrapper5);
                    }
                });
            }

            //官方平台
            QueryWrapper<ShipProductChannelOnlineSelfPlatform> queryWrapper4 = new QueryWrapper<>();
            queryWrapper4.lambda().eq(ShipProductChannelOnlineSelfPlatform::getStrategyId,strategy.getId());
            shipProductChannelOnlineSelfPlatformMapper.delete(queryWrapper4);
            //第三方平台
            QueryWrapper<ShipProductChannelOnlineThirdPlatform> queryWrapper5 = new QueryWrapper<>();
            queryWrapper5.lambda().eq(ShipProductChannelOnlineThirdPlatform::getStrategyId,strategy.getId());
            shipProductChannelOnlineThirdPlatformMapper.delete(queryWrapper5);
        }
    }

    @Override
    public Result<List<ShipProductSaleStrategyDTO2>> shipProductEditDetai(ShipProductEditReq shipProductEditReq) {
        List<ShipProductSaleStrategyDTO2> saleStrategyDTOS = new ArrayList<>();
        QueryWrapper<ShipProductSaleStrategy> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("product_id", shipProductEditReq.getId());
        List<ShipProductSaleStrategy> strategies = shipProductSaleStrategyMapper.selectList(queryWrapper);

        if (org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty(strategies)) {
            for (ShipProductSaleStrategy strategy : strategies) {
                ShipProductSaleStrategyDTO2 scenicProductSaleStrategyDTO = new ShipProductSaleStrategyDTO2();
                //1.策略名称
                scenicProductSaleStrategyDTO.setName(strategy.getName());
                //2.设置策略有效期
                setValidDate(strategy, scenicProductSaleStrategyDTO);
                scenicProductSaleStrategyDTO.setId(strategy.getId());

                //3.设置加幅策略
                setChannelSaleStrategy(strategy,saleStrategyDTOS,scenicProductSaleStrategyDTO);
            }
        }
        return Result.success(saleStrategyDTOS);
    }

    @Override
    public Result<ShipProductDetailDTO2> queryProductDetail(ShipProductReq2 shipProductReq2) throws ParseException {
        //日历渠道加幅策略
        ShipProductDetailDTO2 scenicProductDetailDTO = new ShipProductDetailDTO2();
        ShipProductReservationSettings shipProductReservationSettings = shipProductReservationSettingsMapper.selectOne(
                new QueryWrapper<ShipProductReservationSettings>().lambda().eq(ShipProductReservationSettings::getShipProductId, shipProductReq2.getProductId()));

        //1.封装产品基本信息
        warpperProductBaseInfo(scenicProductDetailDTO, shipProductReservationSettings);

        //2.日期对应加幅策略结果集
        scenicProductDetailDTO.setVaildDateDTOList(composeChannelStrategyByDate(scenicProductDetailDTO,shipProductReservationSettings,shipProductReq2));

        return Result.success(scenicProductDetailDTO);
    }



    /**
     * 封装有效期对应的渠道加幅策略信息
     * @param scenicProductDetailDTO
     * @param scenicProduct
     * @param localFunProductReq
     * @return
     */
    private List<VaildDateDTO> composeChannelStrategyByDate(ShipProductDetailDTO2 scenicProductDetailDTO, ShipProductReservationSettings scenicProduct, ShipProductReq2 localFunProductReq) throws ParseException {
        List<OfflineCanalListDTO> offlineCanalListDTOList = Lists.newArrayListWithExpectedSize(10);
        List<OnlineSelfListDTO> onlineSelfListDTOList = Lists.newArrayListWithExpectedSize(10);
        List<VaildDateDTO> validDateDTOList = Lists.newArrayListWithExpectedSize(10);

        QueryWrapper<ShipProductSaleStrategy> wrapper=new QueryWrapper<>();
        wrapper.eq("product_id",localFunProductReq.getProductId());
        wrapper.eq("is_deleted",0);
        List<ShipProductSaleStrategy> list = shipProductSaleStrategyMapper.selectList(wrapper);
        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isEmpty(list)){
            return validDateDTOList;
        }

        for(ShipProductSaleStrategy scenicProductSaleStrategy : list){
            QueryWrapper<ShipProductChannelOffline> offlineQueryWrapper = new QueryWrapper<>();
            offlineQueryWrapper.eq("is_deleted",0);
            offlineQueryWrapper.eq("strategy_id",scenicProductSaleStrategy.getId());
            offlineQueryWrapper.in("visable_type",new Integer[]{2,3});
            List<ShipProductChannelOffline> scenicProductChannelOfflineList = shipProductChannelOfflineMapper.selectList(offlineQueryWrapper);

            //线下渠道展示列表 = 指定部門/人員 + 代理商
            if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(scenicProductChannelOfflineList)){
                ShipProductChannelOffline channelOffLine = scenicProductChannelOfflineList.stream().findFirst().get();

                //<1>.添加线下自营渠道->offlineCanalListDTOList
                addSelCustomStrategyToOffLineDTO(offlineCanalListDTOList,channelOffLine);

                //<2>.封装线下代理商渠道->offlineCanalListDTOList
                addAgentStrategyToOffLineDTO(offlineCanalListDTOList,channelOffLine);

            }

            //<3>.添加官方平台渠道->onlineSelfListDTOList
            addOnlineOfficePlatformToOnlineDTO(onlineSelfListDTOList,scenicProductSaleStrategy);

            //<4>.添加第三方平台渠道->onlineSelfListDTOList
            addOnlineOtherPlatformToOnlineDTO(onlineSelfListDTOList,scenicProductSaleStrategy);

            //<5>.封装加幅有效期
            addValidDateToDTO(localFunProductReq,validDateDTOList,scenicProductSaleStrategy,offlineCanalListDTOList,onlineSelfListDTOList);

        }
        return validDateDTOList;
    }

    public static final Map<Integer, Map<Integer,List<LocalDate>>> validateTimeMap = Maps.newConcurrentMap();
    /**
     * 封装加幅有效期
     * @param localFunProductReq
     * @param validDateDTOList
     * @param saleStrategy
     * @param offlineCanalListDTOList
     * @param onlineSelfListDTOList
     */
    private void addValidDateToDTO(ShipProductReq2 localFunProductReq, List<VaildDateDTO> validDateDTOList, ShipProductSaleStrategy saleStrategy,
                                   List<OfflineCanalListDTO> offlineCanalListDTOList, List<OnlineSelfListDTO> onlineSelfListDTOList) throws ParseException{
        //获取加幅策略有效期结果集
        QueryWrapper<ShipProductSaleStrategyVaildDate> vaildDateQueryWrapper = new QueryWrapper<>();
        vaildDateQueryWrapper.eq("strategy_id",saleStrategy.getId());
        List<ShipProductSaleStrategyVaildDate> vaildDateList = shipProductSaleStrategyVaildDateMapper.selectList(vaildDateQueryWrapper);

        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isEmpty(vaildDateList)) {
            return;
        }
        //查询条件：年-月
        int year = Integer.parseInt(localFunProductReq.getYear());
        int month = Integer.parseInt(localFunProductReq.getMonth());

        validateTimeMap.clear();
        //缓存日期 - 解决时间段跨月份，月份数据缺失的问题
        cacheValidate(validateTimeMap,vaildDateList);

        if(validateTimeMap.get(year) == null){
            return;
        }
        List<LocalDate> dateTimeList = validateTimeMap.get(year).get(month);
        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(dateTimeList)){
            dateTimeList.forEach(localDateTime->{
                VaildDateDTO vaildDateDTO = new VaildDateDTO();
                vaildDateDTO.setDate(DateUtil.fmtLocalDate(localDateTime,"yyyy-MM-dd"));
                vaildDateDTO.setOnlineSelfListDTOList(onlineSelfListDTOList);
                vaildDateDTO.setOfflineCanalListDTOList(offlineCanalListDTOList);
                validDateDTOList.add(vaildDateDTO);
            });
        }
    }

    /**
     * 缓存日期 - 解决时间段跨月份，月份数据缺失的问题
     *
     * @param validateMap
     * @param vaildDateList
     */
    private void cacheValidate(Map<Integer,Map<Integer, List<LocalDate>>> validateMap, List<ShipProductSaleStrategyVaildDate> vaildDateList) {
        vaildDateList.forEach(entity->{
            List<LocalDate> dateTimeList = Stream.iterate(entity.getTimeBegin(), date -> date.plusDays(1))
                    .limit(ChronoUnit.DAYS.between(entity.getTimeBegin(), entity.getTimeEnd()))
                    .collect(Collectors.toList());
            dateTimeList.add(entity.getTimeEnd());

            Map<Integer, List<LocalDate>> timeYearMap = dateTimeList.stream().collect(Collectors.groupingBy(LocalDate::getYear));
            timeYearMap.forEach((key,val)->{
                Map<Integer, List<LocalDate>> timeMonthMap = val.stream().collect(Collectors.groupingBy(LocalDate::getMonthValue));
                validateMap.put(key,timeMonthMap);
            });
        });
    }

    /**
     * 封装第三方平台加幅信息结果集
     * @param onlineSelfListDTOList
     * @param scenicProductSaleStrategy
     */
    private void addOnlineOtherPlatformToOnlineDTO(List<OnlineSelfListDTO> onlineSelfListDTOList, ShipProductSaleStrategy scenicProductSaleStrategy) {
        //查询第三方渠道
        QueryWrapper<ShipProductChannelOnlineThirdPlatform> thirdPlatformQueryWrapper = new QueryWrapper<>();
        thirdPlatformQueryWrapper.eq("is_deleted",0);
        thirdPlatformQueryWrapper.eq("product_id",scenicProductSaleStrategy.getProductId());
        List<ShipProductChannelOnlineThirdPlatform> thirdPlatformList = shipProductChannelOnlineThirdPlatformMapper.selectList(thirdPlatformQueryWrapper);
        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(thirdPlatformList)){
            for(ShipProductChannelOnlineThirdPlatform thirdPlatform : thirdPlatformList){
                OnlineSelfListDTO onlineSelfListDTO = new OnlineSelfListDTO();
                //1.设置渠道名称
                onlineSelfListDTO.setCanal(thirdPlatform.getPlatformName());
                if(ProductCenterEnum.AMOUNT.getChannelCode().equals(thirdPlatform.getAdjustType())){
                    onlineSelfListDTO.setAddSize("HKD " + thirdPlatform.getAmount().toString());
                }else {
                    onlineSelfListDTO.setAddSize(thirdPlatform.getPercent().toString() + "%");
                }

                //2.设置加幅字符串20HKD
                if(ProductCenterEnum.AMOUNT.getChannelCode().equals(thirdPlatform.getAdjustType())){
                    onlineSelfListDTO.setAddSize("HKD " + thirdPlatform.getAmount().toString());
                }else {
                    onlineSelfListDTO.setAddSize(thirdPlatform.getPercent().toString() + "%");
                }

                //3.设置每日可售数；是否设置限制
                if(ProductCenterEnum.IS_NOT_LIMIT.getChannelCode().equals(thirdPlatform.getIsLimit())){
                    onlineSelfListDTO.setLimitNum(ProductCenterEnum.IS_NOT_LIMIT.getChannelname());
                }else {
                    onlineSelfListDTO.setLimitNum(thirdPlatform.getLimitNum().toString());
                }

                //4.今日已售数  条件：线上、第三方平台
                List<ShipProductSaleRecord> currentSaleRecords = shipProductSaleRecordMapper.getCurrentSaleRecord(thirdPlatform.getProductId(),3,null,1);
                if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(currentSaleRecords)){
                    //今日已售数
                    int sum = currentSaleRecords.stream().mapToInt(ShipProductSaleRecord::getSoldNumber).sum();
                    onlineSelfListDTO.setSoldToday(sum);
                    if(ProductCenterEnum.IS_LIMIT.getChannelCode().equals(thirdPlatform.getIsLimit())){
                        //剩余可售数
                        onlineSelfListDTO.setSurplusStock(Integer.valueOf(onlineSelfListDTO.getLimitNum())-sum);
                    }
                }else {
                    onlineSelfListDTO.setSoldToday(0);
                    onlineSelfListDTO.setSurplusStock(Integer.valueOf(onlineSelfListDTO.getLimitNum()));
                }
                onlineSelfListDTOList.add(onlineSelfListDTO);
            }
        }
    }

    /**
     * 添加线下自营加幅信息列表-提供详情日历展示列表
     * @param offlineCanalListDTOList
     * @param channelOffLine
     */
    private void addSelCustomStrategyToOffLineDTO(List<OfflineCanalListDTO> offlineCanalListDTOList, ShipProductChannelOffline channelOffLine) {
        QueryWrapper<ShipProductChannelOfflineSelfCustom> customQueryWrapper = new QueryWrapper<>();
        customQueryWrapper.eq("is_deleted",0);
        customQueryWrapper.eq("product_id",channelOffLine.getProductId());
        //查询出线下渠道集合
        List<ShipProductChannelOfflineSelfCustom> channelOfflineSelfCustoms = shipProductChannelOfflineSelfCustomMapper.selectList(customQueryWrapper);

        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(channelOfflineSelfCustoms)){
            for(ShipProductChannelOfflineSelfCustom custom : channelOfflineSelfCustoms){
                if(custom.getCheckType() == null){
                    continue;
                }
                OfflineCanalListDTO offlineCanalListDTO = new OfflineCanalListDTO();

                //1.设置渠道名称：部门名称/人员名称 ；勾选人： 2 勾选部门： 1
//                if(custom.getRelationId() != null && custom.getRelationId() != 0L){
//                    if(ProductCenterEnum.PERSONAL_CHOOSE == custom.getCheckType()){
//                        SysDepartmentDTO sysDepartmentDTO = departmentService.queryByUserId(custom.getRelationId());
//                        offlineCanalListDTO.setCanal(sysDepartmentDTO.getTitle());
//                    }else{
//                        UserDTO userDTO = iSysUserService.loadUserByParam(custom.getRelationId(), 1);
//                        offlineCanalListDTO.setCanal(userDTO.getUsername());
//                    }
//                }
                if(channelOffLine.getVisableType() == 2){
                    offlineCanalListDTO.setCanal("所有部門");
                }else {
                    offlineCanalListDTO.setCanal(custom.getName());
                }


                //2.设置加幅字符串 20HKD；加幅类型: 金额 1，百分比 2
                if(ProductCenterEnum.AMOUNT.getChannelCode().equals(custom.getAdjustType())){
                    offlineCanalListDTO.setAddSize("HKD " + custom.getAmount().toString());
                } else {
                    offlineCanalListDTO.setAddSize(custom.getPercent().toString() + "%");
                }

                //3.设置每日可售数；是否设置限购
                if(ProductCenterEnum.IS_NOT_LIMIT.getChannelCode().equals(custom.getIsLimit())){
                    offlineCanalListDTO.setLimitNum(ProductCenterEnum.IS_NOT_LIMIT.getChannelname());
                    offlineCanalListDTO.setSurplusStock("-");
                }else {
                    offlineCanalListDTO.setLimitNum(Objects.isNull(custom.getLimitNum())?null:custom.getLimitNum().toString());
                }

                //4.今日已售数  条件：线下、自营
                List<ShipProductSaleRecord> currentSaleRecords = shipProductSaleRecordMapper.getCurrentSaleRecord(custom.getProductId(),1,custom.getCheckType(),2);
                if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(currentSaleRecords)){
                    //今日已售数
                    int sum = currentSaleRecords.stream().mapToInt(ShipProductSaleRecord::getSoldNumber).sum();
                    offlineCanalListDTO.setSoldToday(sum+"");
                    if(ProductCenterEnum.IS_LIMIT.getChannelCode().equals(custom.getIsLimit())){
                        //剩余可售数
                        offlineCanalListDTO.setSurplusStock(String.valueOf(Integer.valueOf(offlineCanalListDTO.getLimitNum())-sum));
                    }
                }else {
                    offlineCanalListDTO.setSoldToday(0+"");
                    offlineCanalListDTO.setSurplusStock(offlineCanalListDTO.getLimitNum());
                }
                offlineCanalListDTOList.add(offlineCanalListDTO);
            }
        }
    }


    private void addAgentStrategyToOffLineDTO(List<OfflineCanalListDTO> offlineCanalListDTOList, ShipProductChannelOffline channelOffLine) {
        QueryWrapper<ShipProductChannelOfflineAgentCustom> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_deleted",0);
        queryWrapper.eq("product_id",channelOffLine.getProductId());
        List<ShipProductChannelOfflineAgentCustom> agentCustoms = shipProductChannelOfflineAgentCustomMapper.selectList(queryWrapper);
        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(agentCustoms)){
            for(ShipProductChannelOfflineAgentCustom custom : agentCustoms){
                OfflineCanalListDTO offlineCanalListDTO = new OfflineCanalListDTO();
                if(channelOffLine.getVisableType() == 2){
                    offlineCanalListDTO.setCanal("所有代理");
                }else {
                    //1.设置指定代理商名称
                    offlineCanalListDTO.setCanal(custom.getAgentName());
                }

                //2.设置加幅字符串 20HKD；加幅类型: 金额 1，百分比 2
                if(ProductCenterEnum.AMOUNT.getChannelCode().equals(custom.getAdjustType())){
                    offlineCanalListDTO.setAddSize("HKD " + custom.getAmount().toString());
                } else{
                    offlineCanalListDTO.setAddSize(custom.getPercent().toString() + "%");
                }

                //3.设置今日可售数量；是否设置限购
                if(ProductCenterEnum.IS_NOT_LIMIT.getChannelCode().equals(custom.getIsLimit())){
                    offlineCanalListDTO.setLimitNum(ProductCenterEnum.IS_NOT_LIMIT.getChannelname());
                }else {
                    offlineCanalListDTO.setLimitNum(Objects.isNull(custom.getLimitNum())?null:custom.getLimitNum().toString());
                }

                //4.今日已售数  条件：线下、代理商
                List<ShipProductSaleRecord> currentSaleRecords = shipProductSaleRecordMapper.getCurrentSaleRecord(custom.getProductId(),2,null,2);
                if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(currentSaleRecords)){
                    //今日已售数
                    int sum = currentSaleRecords.stream().mapToInt(ShipProductSaleRecord::getSoldNumber).sum();
                    offlineCanalListDTO.setSoldToday(sum+"");
                    if(ProductCenterEnum.IS_LIMIT.getChannelCode().equals(custom.getIsLimit())){
                        //剩余可售数
                        offlineCanalListDTO.setSurplusStock(String.valueOf(Integer.valueOf(offlineCanalListDTO.getLimitNum())-sum));
                    }
                }else {
                    offlineCanalListDTO.setSoldToday(0+"");
                    offlineCanalListDTO.setSurplusStock(offlineCanalListDTO.getLimitNum());
                }
                offlineCanalListDTOList.add(offlineCanalListDTO);
            }
        }

    }

    /**
     * 封装官方平台加幅信息结果集
     * @param onlineSelfListDTOList
     * @param scenicProductSaleStrategy
     */
    private void addOnlineOfficePlatformToOnlineDTO(List<OnlineSelfListDTO> onlineSelfListDTOList, ShipProductSaleStrategy scenicProductSaleStrategy) {
        QueryWrapper<ShipProductChannelOnlineSelfPlatform> platformQueryWrapper = new QueryWrapper<>();
        platformQueryWrapper.eq("is_deleted",0);
        platformQueryWrapper.eq("strategy_id",scenicProductSaleStrategy.getId());
        List<ShipProductChannelOnlineSelfPlatform> selfPlatformList = shipProductChannelOnlineSelfPlatformMapper.selectList(platformQueryWrapper);

        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(selfPlatformList)){
            for(ShipProductChannelOnlineSelfPlatform selfPlatform : selfPlatformList){
                OnlineSelfListDTO onlineSelfListDTO = new OnlineSelfListDTO();

                //1.设置渠道名称
//                if(selfPlatform.getChannelId() == 0){
//                    onlineSelfListDTO.setCanal(ScenicChannelType.APP.getName());
//                }else if(selfPlatform.getChannelId() == 1){
//                    onlineSelfListDTO.setCanal(ScenicChannelType.CHINA_SCENIC.getName());
//                }
                onlineSelfListDTO.setCanal(selfPlatform.getChannelName());

                //2.设置加幅字符串20HKD
                if(ProductCenterEnum.AMOUNT.getChannelCode().equals(selfPlatform.getAdjustType())){
                    onlineSelfListDTO.setAddSize("HKD " + selfPlatform.getAmount().toString());
                }else {
                    onlineSelfListDTO.setAddSize(selfPlatform.getPercent().toString() + "%");
                }

                //3.设置今日可售数；是否设置限制
                if(ProductCenterEnum.IS_NOT_LIMIT.equals(selfPlatform.getIsLimit())){
                    onlineSelfListDTO.setLimitNum(ProductCenterEnum.IS_NOT_LIMIT.getChannelname());
                }else {
                    onlineSelfListDTO.setLimitNum(selfPlatform.getLimitNum().toString());
                }

                //4.今日已售数  条件：线上、第三方平台
                List<ShipProductSaleRecord> currentSaleRecords = shipProductSaleRecordMapper.getCurrentSaleRecord(selfPlatform.getProductId(),4,null,1);
                if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(currentSaleRecords)){
                    //今日已售数
                    int sum = currentSaleRecords.stream().mapToInt(ShipProductSaleRecord::getSoldNumber).sum();
                    onlineSelfListDTO.setSoldToday(sum);
                    if(ProductCenterEnum.IS_LIMIT.getChannelCode().equals(selfPlatform.getIsLimit())){
                        //剩余可售数
                        onlineSelfListDTO.setSurplusStock(Integer.valueOf(onlineSelfListDTO.getLimitNum())-sum);
                    }
                }else {
                    onlineSelfListDTO.setSoldToday(0);
                    onlineSelfListDTO.setSurplusStock(Integer.valueOf(onlineSelfListDTO.getLimitNum()));
                }
                onlineSelfListDTOList.add(onlineSelfListDTO);
            }
        }
    }

    private void warpperProductBaseInfo(ShipProductDetailDTO2 scenicProductDetailDTO, ShipProductReservationSettings scenicProduct) {
        ShipProduct shipProduct = shipProductMapper.selectById(scenicProduct.getShipProductId());
        if(shipProduct == null){
            throw new BusinessException(SystemError.SHIP_PRODUCT_11032);
        }
        ShipProductListDTO scenicProductListDTO = new ShipProductListDTO();
        if(shipProduct != null){
            scenicProductListDTO = EntityUtil.copy(shipProduct, ShipProductListDTO.class);
        }
        if(scenicProduct != null){
            if((scenicProduct.getServiceChargeType() != null) && scenicProduct.getServiceChargeType() == 1){
                //类型是加数值
                scenicProductListDTO.setServiceChargePrice(scenicProduct.getServiceChargePrice().toString() + "HKD");
            }else if((scenicProduct.getServiceChargeType() != null) && scenicProduct.getServiceChargeType() == 2){
                //类型是百分比
                scenicProductListDTO.setServiceChargePrice(scenicProduct.getServiceChargePrice().toString() + "%");
            }
            if((scenicProduct.getRefundFeeType() != null) && scenicProduct.getRefundFeeType() == 1){
                //类型是加数值
                scenicProductListDTO.setRefundFeePrice(scenicProduct.getRefundFeePrice() + "HKD");
            }else if((scenicProduct.getRefundFeeType() != null) && scenicProduct.getRefundFeeType() == 2){
                //类型是百分比
                scenicProductListDTO.setRefundFeePrice(scenicProduct.getRefundFeePrice() + "%");
            }
            scenicProductListDTO.setSaleBeginDate(scenicProduct.getSaleBeginDate());
            scenicProductListDTO.setSaleEndDate(scenicProduct.getSaleEndDate());
            scenicProductListDTO.setBookingInformation(scenicProduct.getBookingInformation());
            scenicProductListDTO.setCancelStrategy(scenicProduct.getCancelStrategy());
            scenicProductDetailDTO.setScenicProductListDTO(scenicProductListDTO);
        }
    }

    private void setChannelSaleStrategy(ShipProductSaleStrategy strategy, List<ShipProductSaleStrategyDTO2> saleStrategyDTOS, ShipProductSaleStrategyDTO2 scenicProductSaleStrategyDTO) {
        ChannelSaleDTO channelSaleDTO = new ChannelSaleDTO();

        ShipProductOfflineChannelDTO scenicProductOfflineChannelDTO = new ShipProductOfflineChannelDTO();
        //自营渠道
        QueryWrapper<ShipProductChannelOffline> offlineQueryWrapper = new QueryWrapper<>();
        offlineQueryWrapper.eq("product_id", strategy.getProductId());
        offlineQueryWrapper.eq("strategy_id", strategy.getId());
        List<ShipProductChannelOffline> channelOfflines = shipProductChannelOfflineMapper.selectList(offlineQueryWrapper);

        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(channelOfflines)){

            for(ShipProductChannelOffline channelOffline : channelOfflines){
                if (channelOffline.getChannelType() == 1) {
                    if (channelOffline.getVisableType() == 1) {
                        scenicProductOfflineChannelDTO.setVisableType(1);
                        scenicProductOfflineChannelDTO.setOfflineSelfId(channelOffline.getId());
                    }
                    else if (channelOffline.getVisableType() == 2) {
                        QueryWrapper<ShipProductChannelOfflineSelfCustom> selfCustomQueryWrapper = new QueryWrapper<>();
                        selfCustomQueryWrapper.eq("product_id",strategy.getProductId());
                        selfCustomQueryWrapper.eq("offline_id",channelOffline.getId());
                        ShipProductChannelOfflineSelfCustom selfCustom = shipProductChannelOfflineSelfCustomMapper.selectOne(selfCustomQueryWrapper);
                        if(selfCustom != null){
                            scenicProductOfflineChannelDTO = EntityUtil.copy(selfCustom, ShipProductOfflineChannelDTO.class);
                            scenicProductOfflineChannelDTO.setVisableType(channelOffline.getVisableType());
                        }
                    } else if(channelOffline.getVisableType() == 3){
                        scenicProductOfflineChannelDTO.setVisableType(3);
                        scenicProductOfflineChannelDTO.setOfflineSelfId(channelOffline.getId());
                        List<ShipProductChannelOfflineSelfCustomDTO2> scenicProductChannelOfflineSelfCustomDTOList = new ArrayList<>();
                        QueryWrapper<ShipProductChannelOfflineSelfCustom> selfCustomQueryWrapper = new QueryWrapper<>();
                        selfCustomQueryWrapper.eq("product_id",strategy.getProductId());
                        selfCustomQueryWrapper.eq("offline_id",channelOffline.getId());
                        selfCustomQueryWrapper.eq("is_deleted",0);
                        List<ShipProductChannelOfflineSelfCustom> selfCustoms = shipProductChannelOfflineSelfCustomMapper.selectList(selfCustomQueryWrapper);
                        if(org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty(selfCustoms)){
                            for(ShipProductChannelOfflineSelfCustom selfCustom : selfCustoms){
                                ShipProductChannelOfflineSelfCustomDTO2 scenicProductChannelOfflineSelfCustomDTO = EntityUtil.copy(selfCustom, ShipProductChannelOfflineSelfCustomDTO2.class);
                                scenicProductChannelOfflineSelfCustomDTOList.add(scenicProductChannelOfflineSelfCustomDTO);
                                scenicProductOfflineChannelDTO.setScenicProductChannelOfflineSelfCustomDTOList(scenicProductChannelOfflineSelfCustomDTOList);
                            }
                        }
                    }
                    channelSaleDTO.setScenicProductOfflineChannelDTO(scenicProductOfflineChannelDTO);
                }else if(channelOffline.getChannelType() == 2){
                    //代理商
                    ShipProductAgentDTO scenicProductAgentDTO = new ShipProductAgentDTO();
                    if (channelOffline.getVisableType() == 1) {
                        scenicProductAgentDTO.setVisableType(1);
                        scenicProductAgentDTO.setOfflineAgentId(channelOffline.getId());
                    }
                    else if (channelOffline.getVisableType() == 2) {
                        QueryWrapper<ShipProductChannelOfflineAgentCustom> customQueryWrapper = new QueryWrapper<>();
                        customQueryWrapper.eq("product_id",strategy.getProductId());
                        customQueryWrapper.eq("offline_id",channelOffline.getId());
                        customQueryWrapper.eq("is_deleted",0);
                        ShipProductChannelOfflineAgentCustom agentCustom = shipProductChannelOfflineAgentCustomMapper.selectOne(customQueryWrapper);
                        if(null != agentCustom){
                            scenicProductAgentDTO = EntityUtil.copy(agentCustom, ShipProductAgentDTO.class);
                            scenicProductAgentDTO.setVisableType(channelOffline.getChannelType());
                        }
                    }else if(channelOffline.getVisableType() == 3){
                        scenicProductAgentDTO.setVisableType(3);
                        scenicProductAgentDTO.setOfflineAgentId(channelOffline.getId());
                        List<ShipProductChannelOfflineAgentCustomDTO2> scenicProductChannelOfflineAgentCustomDTOList = new ArrayList<>();
                        QueryWrapper<ShipProductChannelOfflineAgentCustom> customQueryWrapper = new QueryWrapper<>();
                        customQueryWrapper.eq("product_id",strategy.getProductId());
                        customQueryWrapper.eq("offline_id",channelOffline.getId());
                        customQueryWrapper.eq("is_deleted",0);
                        List<ShipProductChannelOfflineAgentCustom> agentCustomList = shipProductChannelOfflineAgentCustomMapper.selectList(customQueryWrapper);
                        if(org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty(agentCustomList)){
                            for(ShipProductChannelOfflineAgentCustom agentCustom : agentCustomList){
                                ShipProductChannelOfflineAgentCustomDTO2 agentCustomDTO = EntityUtil.copy(agentCustom, ShipProductChannelOfflineAgentCustomDTO2.class);
                                agentCustomDTO.setVisableType("3");
                                scenicProductChannelOfflineAgentCustomDTOList.add(agentCustomDTO);
                            }
                            scenicProductAgentDTO.setScenicProductChannelOfflineAgentCustomDTOList(scenicProductChannelOfflineAgentCustomDTOList);
                        }
                    }
                    channelSaleDTO.setScenicProductAgentDTO(scenicProductAgentDTO);
                }
            }
        }


        //线上官方平台
        List<ShipProductChannelOnlineSelfPlatformDTO2> selfPlatformDTOList = new ArrayList<>();
        QueryWrapper<ShipProductChannelOnlineSelfPlatform> platformQueryWrapper = new QueryWrapper<>();
        platformQueryWrapper.eq("is_deleted",0);
        platformQueryWrapper.eq("product_id",strategy.getProductId());
        List<ShipProductChannelOnlineSelfPlatform> selfPlatformList = shipProductChannelOnlineSelfPlatformMapper.selectList(platformQueryWrapper);
        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(selfPlatformList)){
            for(ShipProductChannelOnlineSelfPlatform selfPlatform : selfPlatformList){
                ShipProductChannelOnlineSelfPlatformDTO2 selfPlatformDTO = EntityUtil.copy(selfPlatform, ShipProductChannelOnlineSelfPlatformDTO2.class);
                selfPlatformDTOList.add(selfPlatformDTO);
            }
            channelSaleDTO.setScenicProductChannelOnlineSelfPlatformDTOList(selfPlatformDTOList);
        }
        //第三方平台
        List<ShipProductChannelOnlineThirdPlatformDTO2> scenicProductChannelOnlineThirdPlatformDTOList = new ArrayList<>();
        QueryWrapper<ShipProductChannelOnlineThirdPlatform> scenicProductChannelOnlineThirdPlatformQueryWrapper = new QueryWrapper();
        scenicProductChannelOnlineThirdPlatformQueryWrapper.eq("product_id",strategy.getProductId());
        List<ShipProductChannelOnlineThirdPlatform> platforms = shipProductChannelOnlineThirdPlatformMapper.selectList(scenicProductChannelOnlineThirdPlatformQueryWrapper);
        if(org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty(platforms)){
            for(ShipProductChannelOnlineThirdPlatform selfPlatform : platforms){
                ShipProductChannelOnlineThirdPlatformDTO2 scenicProductChannelOnlineThirdPlatformDTO = EntityUtil.copy(selfPlatform, ShipProductChannelOnlineThirdPlatformDTO2.class);
                scenicProductChannelOnlineThirdPlatformDTOList.add(scenicProductChannelOnlineThirdPlatformDTO);
            }
            channelSaleDTO.setScenicProductChannelOnlineThirdPlatformDTOList(scenicProductChannelOnlineThirdPlatformDTOList);
        }
        scenicProductSaleStrategyDTO.setChannelSaleDTO(channelSaleDTO);
        saleStrategyDTOS.add(scenicProductSaleStrategyDTO);
    }


    /**
     * 设置策略有效期
     * @param strategy
     * @param scenicProductSaleStrategyDTO
     */
    private void setValidDate(ShipProductSaleStrategy strategy, ShipProductSaleStrategyDTO2 scenicProductSaleStrategyDTO) {
        QueryWrapper<ShipProductSaleStrategyVaildDate> vaildDateQueryWrapper = new QueryWrapper<>();
        vaildDateQueryWrapper.eq("strategy_id", strategy.getId());
        List<ShipProductSaleStrategyVaildDate> list = shipProductSaleStrategyVaildDateMapper.selectList(vaildDateQueryWrapper);
        List<ShipTimeDTO> timeDTOList = new ArrayList<>();
        if (org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty(list)) {
            for (ShipProductSaleStrategyVaildDate vaildDate : list) {
                ShipTimeDTO scenicTimeDTO = new ShipTimeDTO();
                scenicTimeDTO.setBeginTime(vaildDate.getTimeBegin());
                scenicTimeDTO.setEndTime(vaildDate.getTimeEnd());
                scenicTimeDTO.setTimeId(vaildDate.getId());
                timeDTOList.add(scenicTimeDTO);
            }
        }
        scenicProductSaleStrategyDTO.setTime(timeDTOList);
    }

    /**
     * 設置渠道加幅
     * @param strategyId
     * @param shipProductPutReq
     * @param productId
     * @param userId
     */
    private void addChannelSale(Long strategyId, ShipProductPutReq shipProductPutReq, Long productId, Long userId) {
        ChannelSaleReq channelSaleReq = shipProductPutReq.getChannelSaleReq();

        //1.新增线下自营渠道
        addOffLineSelCustom(channelSaleReq,productId,userId,strategyId);

        //2.新增线下代理商
        addOffLineAgent(channelSaleReq,productId,userId,strategyId);

        //3.新增线上官方平台
        addOnLineOfficePlatForm(channelSaleReq,productId,userId,strategyId);

        //4.新增线上第三方平台
        addOnLineOtherPlatform(channelSaleReq,productId,userId,strategyId);


    }

    /**
     * 設置第三方平台加幅
     * @param channelSaleReq
     * @param productId
     * @param userId
     * @param strategyId
     */
    private void addOnLineOtherPlatform(ChannelSaleReq channelSaleReq, Long productId, Long userId, Long strategyId) {
        List<ShipChannelOnlineThirdPlatformReq> thirdPlatformReqList = channelSaleReq.getLocalFunProductChannelOnlineThirdPlatformReqList();
        if(CollectionUtils.isEmpty(thirdPlatformReqList)){
            return;
        }
        for (ShipChannelOnlineThirdPlatformReq req1 : thirdPlatformReqList) {

            ShipProductChannelOnlineThirdPlatform LocalFunProductChannelOnlineThirdPlatform = ShipProductChannelOnlineThirdPlatform.builder().productId(productId)
                    .isDeleted(0).strategyId(strategyId).createId(userId).platformId(req1.getPlatformId())
                    .platformName(req1.getPlatformName()).build();

            LocalFunProductChannelOnlineThirdPlatform.setGmtCreate(LocalDateTime.now());
            LocalFunProductChannelOnlineThirdPlatform.setAdjustType(req1.getAdjustType());
            LocalFunProductChannelOnlineThirdPlatform.setAmount(req1.getAmount());
            LocalFunProductChannelOnlineThirdPlatform.setPercent(req1.getPercent());

            if (req1.getIsLimit() == null || req1.getIsLimit() == 0) {
                LocalFunProductChannelOnlineThirdPlatform.setIsLimit(0);
            } else {
                LocalFunProductChannelOnlineThirdPlatform.setIsLimit(1);
                LocalFunProductChannelOnlineThirdPlatform.setLimitNum(req1.getLimitNum());
            }

            LocalFunProductChannelOnlineThirdPlatform.setId(SnowflakeIdWorker.nextId());
            shipProductChannelOnlineThirdPlatformMapper.insert(LocalFunProductChannelOnlineThirdPlatform);

        }

    }

    /**
     * 設置官方平台加幅
     * @param channelSaleReq
     * @param productId
     * @param userId
     * @param strategyId
     */
    private void addOnLineOfficePlatForm(ChannelSaleReq channelSaleReq, Long productId, Long userId, Long strategyId) {
        List<ShipProductChannelOnlineSelfPlatform2Req> platformReqList = channelSaleReq.getLocalFunProductChannelOnlineSelfPlatformReqList();
        if(CollectionUtils.isEmpty(platformReqList)){
            return;
        }

        for (ShipProductChannelOnlineSelfPlatform2Req req1 : platformReqList) {
            ShipProductChannelOnlineSelfPlatform shipProductChannelOnlineSelfPlatform = ShipProductChannelOnlineSelfPlatform.builder().productId(productId)
                    .strategyId(strategyId).createId(userId).isDeleted(0)
                    .channelId(req1.getChannelId())
                    .channelName(req1.getChannelName()).build();

            shipProductChannelOnlineSelfPlatform.setGmtCreate(LocalDateTime.now());
            shipProductChannelOnlineSelfPlatform.setAdjustType(req1.getAdjustType());
            shipProductChannelOnlineSelfPlatform.setAmount(req1.getAmount());
            shipProductChannelOnlineSelfPlatform.setPercent(req1.getPercent());

            if (req1.getIsLimit() == null || req1.getIsLimit() == 0) {
                shipProductChannelOnlineSelfPlatform.setIsLimit(0);
            } else  {
                shipProductChannelOnlineSelfPlatform.setIsLimit(1);
                shipProductChannelOnlineSelfPlatform.setLimitNum(req1.getLimitNum());
            }

            shipProductChannelOnlineSelfPlatform.setId(SnowflakeIdWorker.nextId());
            shipProductChannelOnlineSelfPlatformMapper.insert(shipProductChannelOnlineSelfPlatform);

        }
    }

    /**
     * 設置代理商加幅
     * @param channelSaleReq
     * @param productId
     * @param userId
     * @param strategyId
     */
    private void addOffLineAgent(ChannelSaleReq channelSaleReq, Long productId, Long userId, Long strategyId) {
        ShipProductAgentReq shipProductAgentReq = channelSaleReq.getLocalFunProductAgentReq();
        if (shipProductAgentReq != null) {
            Long offLineId = SnowflakeIdWorker.nextId();

            //代理商渠道權限
            ShipProductChannelOffline LocalFunProductChannelOffline = ShipProductChannelOffline.builder()
                    .productId(productId).channelType(2).createId(userId).isDeleted(0)
                    .strategyId(strategyId).build();

            //代理商渠道加幅
            ShipProductChannelOfflineAgentCustom LocalFunProductChannelOfflineAgentCustom = ShipProductChannelOfflineAgentCustom.builder()
                    .productId(productId).offlineId(offLineId).createId(userId).build();
            LocalFunProductChannelOfflineAgentCustom.setGmtCreate(LocalDateTime.now());


            /**
             * visableType : 1 自营禁售，2 所有部门 3 指定部门/人员
             */
            switch (shipProductAgentReq.getVisableType()) {
                case SEL_CUSTOM_FORBID:
                    saveOffLineChannel(LocalFunProductChannelOffline, shipProductAgentReq.getOfflineAgentId(), offLineId, SEL_CUSTOM_FORBID,AGENT_CUSTOM);
                    break;
                case ALL_DEPT_SALE:
                    saveOffLineChannel(LocalFunProductChannelOffline, shipProductAgentReq.getOfflineAgentId(), offLineId, ALL_DEPT_SALE,AGENT_CUSTOM);

                    if(shipProductAgentReq.getAmount() != null){
                        LocalFunProductChannelOfflineAgentCustom.setAmount(shipProductAgentReq.getAmount());
                    }
                    if(shipProductAgentReq.getAdjustType() != null){
                        LocalFunProductChannelOfflineAgentCustom.setAdjustType(shipProductAgentReq.getAdjustType());
                    }
                    if(shipProductAgentReq.getPercent() != null){
                        LocalFunProductChannelOfflineAgentCustom.setPercent(shipProductAgentReq.getPercent());
                    }
                    if(shipProductAgentReq.getLimitNum() != null){
                        LocalFunProductChannelOfflineAgentCustom.setLimitNum(shipProductAgentReq.getLimitNum());
                    }
                    if(shipProductAgentReq.getIsLimit() != null){
                        LocalFunProductChannelOfflineAgentCustom.setIsLimit(shipProductAgentReq.getIsLimit());
                    }

                    LocalFunProductChannelOfflineAgentCustom.setId(SnowflakeIdWorker.nextId());
                    shipProductChannelOfflineAgentCustomMapper.insert(LocalFunProductChannelOfflineAgentCustom);

                    break;
                case PERSONAL_SALE:
                    saveOffLineChannel(LocalFunProductChannelOffline, shipProductAgentReq.getOfflineAgentId(), offLineId, PERSONAL_SALE,AGENT_CUSTOM);
                    List<ShipChannelOfflineAgentCustom2Req> shipChannelOfflineAgentCustom2ReqList = shipProductAgentReq.getScenicProductChannelOfflineAgentCustomReqList();
                    if (CollectionUtils.isEmpty(shipChannelOfflineAgentCustom2ReqList)) {
                        break;
                    }
                    for (ShipChannelOfflineAgentCustom2Req req1 : shipChannelOfflineAgentCustom2ReqList) {
                        LocalFunProductChannelOfflineAgentCustom.setAgentId(req1.getAgentId());
                        LocalFunProductChannelOfflineAgentCustom.setAgentName(req1.getAgentName());
                        LocalFunProductChannelOfflineAgentCustom.setAdjustType(req1.getAdjustType());
                        LocalFunProductChannelOfflineAgentCustom.setAmount(req1.getAmount());
                        LocalFunProductChannelOfflineAgentCustom.setPercent(req1.getPercent());

                        if (req1.getIsLimit() == null || req1.getIsLimit() == 0) {
                            LocalFunProductChannelOfflineAgentCustom.setIsLimit(0);
                        } else  {
                            LocalFunProductChannelOfflineAgentCustom.setIsLimit(1);
                            LocalFunProductChannelOfflineAgentCustom.setLimitNum(req1.getLimitNum());
                        }

                        LocalFunProductChannelOfflineAgentCustom.setId(SnowflakeIdWorker.nextId());
                        shipProductChannelOfflineAgentCustomMapper.insert(LocalFunProductChannelOfflineAgentCustom);

                    }

                    break;
                default:
                    break;
            }
        }
    }



    /**
     * 設置線下自營渠道加幅
     * @param channelSaleReq
     * @param productId
     * @param userId
     * @param strategyId
     */
    private void addOffLineSelCustom(ChannelSaleReq channelSaleReq, Long productId, Long userId, Long strategyId) {

        //線下自營渠道加幅策略入參信息
        ShipProductOfflineChannelReq shipProductOfflineChannelReq = channelSaleReq.getLocalFunProductOfflineChannelReq();
        if (shipProductOfflineChannelReq == null) {
            return;
        }

        //設置策略渠道權限
        Long newOfficeId = SnowflakeIdWorker.nextId();
        ShipProductChannelOffline offline = ShipProductChannelOffline.builder().productId(productId)
                //自營渠道
                .channelType(1)
                //策略ID
                .strategyId(strategyId)
                .createId(userId).isDeleted(0).build();
        offline.setGmtCreate(LocalDateTime.now());


        //線下自營渠道加幅
        ShipProductChannelOfflineSelfCustom build = ShipProductChannelOfflineSelfCustom.builder().productId(productId)
                .createId(userId).isDeleted(0).build();
        build.setGmtCreate(LocalDateTime.now());

        /**
         * visableType : 1 自营禁售，2 所有部门 3 指定部门/人员
         */
        switch (shipProductOfflineChannelReq.getVisableType()) {
            case SEL_CUSTOM_FORBID:
                saveOffLineChannel(offline,shipProductOfflineChannelReq.getOfflineSelfId(), newOfficeId,SEL_CUSTOM_FORBID,SEL_CUSTOM);
                break;
            case ALL_DEPT_SALE:
                saveOffLineChannel(offline,shipProductOfflineChannelReq.getOfflineSelfId(), newOfficeId, ALL_DEPT_SALE,SEL_CUSTOM);

                //勾选人/部门类型(1部门，2员工)
                build.setCheckType(1);
                build.setId(shipProductOfflineChannelReq.getRuleId());
                saveProductIncreaseStrategy(shipProductOfflineChannelReq, build, newOfficeId,shipProductOfflineChannelReq.getAdjustType(), 0 == shipProductOfflineChannelReq.getIsLimit());

                break;
            case PERSONAL_SALE:
                saveOffLineChannel(offline, shipProductOfflineChannelReq.getOfflineSelfId(), newOfficeId, PERSONAL_SALE,SEL_CUSTOM);

                //设置指定部門/人員加幅
                List<ShipChannelOfflineSelfCustomReq> offlineSelfCustomReqList = shipProductOfflineChannelReq.getChannelOfflineSelfCustomReqs();
                if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(offlineSelfCustomReqList)){
                    for (ShipChannelOfflineSelfCustomReq customReq : offlineSelfCustomReqList) {
                        build.setCheckType(customReq.getCheckType());
                        build.setName(customReq.getName());
                        build.setRelationId(customReq.getRelationId());
                        build.setId(customReq.getRuleId());
                        shipProductOfflineChannelReq.setAmount(customReq.getAmount());
                        shipProductOfflineChannelReq.setLimitNum(customReq.getLimitNum());
                        shipProductOfflineChannelReq.setPercent(customReq.getPercent());
                        saveProductIncreaseStrategy(shipProductOfflineChannelReq, build, newOfficeId, customReq.getAdjustType(), 0 == customReq.getIsLimit());
                    }
                }
                break;
            default:
                break;
        }
    }

    private void saveProductIncreaseStrategy(ShipProductOfflineChannelReq shipProductOfflineChannelReq, ShipProductChannelOfflineSelfCustom build, Long newOfficeId, Integer adjustType, boolean noLimit) {

        if (AMOUNT == adjustType) {
            build.setAdjustType(AMOUNT);
            build.setAmount(shipProductOfflineChannelReq.getAmount());
        } else {
            build.setAdjustType(PERCENT);
            build.setPercent(shipProductOfflineChannelReq.getPercent());
        }

        if (noLimit) {
            //無限制
            build.setIsLimit(0);
        } else {
            build.setIsLimit(1);
            build.setLimitNum(shipProductOfflineChannelReq.getLimitNum());
        }

        build.setId(SnowflakeIdWorker.nextId());
        build.setOfflineId(newOfficeId);
        shipProductChannelOfflineSelfCustomMapper.insert(build);

    }

    /**
     *
     * @param offline
     * @param oldOfficeId
     * @param newOfficeId
     * @param selCustomForbid
     * @param selCustom
     */
    private void saveOffLineChannel(ShipProductChannelOffline offline, Long oldOfficeId, Long newOfficeId, int selCustomForbid, int selCustom) {
        offline.setId(newOfficeId);
        offline.setVisableType(selCustomForbid);
        shipProductChannelOfflineMapper.insert(offline);
    }


    /**
     * 自營渠道
     * 刪除部門或按部門、人員加幅的信息
     * @param id
     * @param visableType
     */
    private void deleteHistoryChannelInfo(Long id, Integer visableType) {
        //權限選擇發誓變化： 1、刪除線下自營渠道配置的幅加表
        ShipProductChannelOffline oldChannelOffline = shipProductChannelOfflineMapper.selectById(id);
        if(!oldChannelOffline.getVisableType().equals(visableType)){
            QueryWrapper<ShipProductChannelOfflineSelfCustom> wrapper2 = new QueryWrapper<>();
            wrapper2.lambda().eq(ShipProductChannelOfflineSelfCustom::getOfflineId,id);
            shipProductChannelOfflineSelfCustomMapper.delete(wrapper2);
        }
    }

    /**
     * 代理商
     * 刪除部門或按部門、人員加幅的信息
     * @param id
     * @param visableType
     */
    private void deleteHistoryAgentChannelInfo(Long id, Integer visableType) {
        //權限選擇發誓變化： 1、刪除線下自營渠道配置的幅加表
        ShipProductChannelOffline oldChannelOffline = shipProductChannelOfflineMapper.selectById(id);
        if(!oldChannelOffline.getVisableType().equals(visableType)){
            QueryWrapper<ShipProductChannelOfflineAgentCustom> wrapper2 = new QueryWrapper<>();
            wrapper2.lambda().eq(ShipProductChannelOfflineAgentCustom::getOfflineId,id);
            shipProductChannelOfflineAgentCustomMapper.delete(wrapper2);
        }
    }


    /**
     * 設置有效期
     * @param productId
     * @param localFunProductSaleStrategyReq
     * @param strategyId
     */
    private void addSaleStrategyValidDate(Long productId, ShipProductPutReq localFunProductSaleStrategyReq, Long strategyId) {
        List<ShipTimeDTO> time = localFunProductSaleStrategyReq.getTime();
        if (com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(time)) {
            time.forEach(entity->{
               ShipProductSaleStrategyVaildDate saleStrategyValidDate = new ShipProductSaleStrategyVaildDate();
                saleStrategyValidDate.setProductId(productId);
                saleStrategyValidDate.setGmtCreate(LocalDateTime.now());
                saleStrategyValidDate.setTimeBegin(entity.getBeginTime());
                saleStrategyValidDate.setTimeEnd(entity.getEndTime());
                saleStrategyValidDate.setStrategyId(strategyId);
                shipProductSaleStrategyVaildDateMapper.insert(saleStrategyValidDate);
            });
        }
    }

    /**
     * 刪除無用的策略
     * @param strategyList
     * @param productId
     */
    private void deleteUnUsedStrategy(List<ShipProductPutReq> strategyList, Long productId) {
        //查詢產品下的策略列表
        List<ShipProductSaleStrategy> strategies = shipProductSaleStrategyMapper.
                selectList(new QueryWrapper<ShipProductSaleStrategy>().lambda().eq(ShipProductSaleStrategy::getProductId, productId));

        if(!CollectionUtils.isEmpty(strategies)){
            List<Long> ids = strategyList.stream().filter(entity -> entity.getIncreaseStrategyId() != null && productId == entity.getProductId())
                    .map(ShipProductPutReq::getIncreaseStrategyId).collect(Collectors.toList());
            //產品下策略ID結果集
            List<Long> strategyIds = strategies.stream().filter(entity->!ids.contains(entity.getId())).map(ShipProductSaleStrategy::getId).collect(Collectors.toList());

            if(!CollectionUtils.isEmpty(strategyIds)){
                shipProductSaleStrategyMapper.deleteBatchIds(strategyIds);
            }
        }
    }

    /**
     * 新增/更新策略
     * @param userId
     * @param productId
     * @param shipProductPutReq
     * @return
     */
    private Long addAndUpdateSaleStrategy(Long userId, Long productId, ShipProductPutReq shipProductPutReq) {
        return addStrategy(userId, productId, shipProductPutReq);
    }

    /**
     * 新增策略
     * @param userId
     * @param productId
     * @param shipProductPutReq
     */
    private Long addStrategy(Long userId, Long productId, ShipProductPutReq shipProductPutReq) {
        Long id = SnowflakeIdWorker.nextId();
        ShipProductSaleStrategy shipProductSaleStrategy = new ShipProductSaleStrategy();
        shipProductSaleStrategy.setId(id);
        shipProductSaleStrategy.setCreateId(userId);
        shipProductSaleStrategy.setIsDeleted(0);
        shipProductSaleStrategy.setGmtCreate(LocalDateTime.now());
        shipProductSaleStrategy.setProductId(productId);
        shipProductSaleStrategy.setName(shipProductPutReq.getName());
        shipProductSaleStrategyMapper.insert(shipProductSaleStrategy);
        return id;
    }

    /**
     * 更新策略
     * @param userId
     * @param shipProductPutReq
     */
    private Long updateStrategy(Long userId, ShipProductPutReq shipProductPutReq) {
        ShipProductSaleStrategy shipProductSaleStrategy = new ShipProductSaleStrategy();
        shipProductSaleStrategy.setId(shipProductPutReq.getIncreaseStrategyId());
        shipProductSaleStrategy.setName(shipProductPutReq.getName());
        shipProductSaleStrategy.setModifiedId(userId);
        shipProductSaleStrategy.setGmtModified(LocalDateTime.now());
        shipProductSaleStrategyMapper.updateById(shipProductSaleStrategy);
        return shipProductPutReq.getIncreaseStrategyId();
    }


    /**
     * 數據校驗
     * @param req
     * @param funProductIdList
     * @param strategyList
     * @return
     */
    private Result checkDataBeforePutAway(ShipProductBatchSaleStrategyReq req, List<Long> funProductIdList, List<ShipProductPutReq> strategyList) {
        //增幅策略空数据校验
        if (checkStrategyEmpty(funProductIdList,strategyList)) {
            return Result.failed(SystemError.LOCAL_FUN_18002);
        }

        //校驗有效期和加幅策略個數
        if(checkStrategyCandidateCount(strategyList)){
            return Result.failed(SystemError.LOCAL_FUN_18005);
        }

        //校验当地玩乐成本有效期是否重复
        if(duplicateDateForUseDate(req)){
            return Result.failed(SystemError.LOCAL_FUN_18003);
        }
        return null;
    }



    /**
     * 增幅策略空数据校验
     * @param funProductIdList
     * @param strategyList
     * @return
     */
    private boolean checkStrategyEmpty(List<Long> funProductIdList, List<ShipProductPutReq> strategyList) {
        return com.github.xiaoymin.knife4j.core.util.CollectionUtils.isEmpty(funProductIdList) || com.github.xiaoymin.knife4j.core.util.CollectionUtils.isEmpty(strategyList);
    }

    /**
     * 校驗有效期和加幅策略個數
     * @param strategyList
     * @return
     */
    private boolean checkStrategyCandidateCount(List<ShipProductPutReq> strategyList) {
        if(strategyList.size() > 5){
            return true;
        }

        for(ShipProductPutReq strategy : strategyList){
            List<ShipTimeDTO> time = strategy.getTime();
            if(time != null && time.size() > 5){
                return true;
            }
        }
        return false;
    }

    /**
     * 校验当地玩乐成本有效期是否重复
     * 思路：1.收集开始日期到结束日期的所有结果集合
     * 2.将日期去重和日期集合总数对比，不相等代表存在重复的有效日期
     * @param req
     * @return
     */
    private boolean duplicateDateForUseDate(ShipProductBatchSaleStrategyReq req) {
        List<ShipProductPutReq> strategyList = req.getStrategyList();
        Set<LocalDate> localDateSet = Sets.newHashSet();
        int localDateSize = 0;
        for (ShipProductPutReq airProductCostDataReq : strategyList) {
            List<ShipTimeDTO> timeDataList = airProductCostDataReq.getTime();
            for (ShipTimeDTO airProductCostDateData : timeDataList) {
                LocalDate dateBegin = airProductCostDateData.getBeginTime();
                LocalDate dateEnd = airProductCostDateData.getEndTime();
                //获取开始日期-结束日期的集合
                List<LocalDate> dates = Stream.iterate(dateBegin, date -> date.plusDays(1))
                        .limit(ChronoUnit.DAYS.between(dateBegin, dateEnd))
                        .collect(Collectors.toList());
                dates.add(dateEnd);
                localDateSet.addAll(dates);
                localDateSize += dates.size();
            }
        }
        return localDateSet.size() != localDateSize;
    }
    /**
     * 产品中心-分页查询船票产品列表
     *
     * @param req
     * @param tokenUser
     * @return
     */
    @Override
    public PageResponse<ShipProductPageDTO> queryList(ShipProductPageReq req, TokenUser tokenUser) {
        //不是管理员
        List<Long> data = Lists.newArrayListWithCapacity(5);
//        if (!GlobalConstants.Role.isAdmin(tokenUser.getUsername())) {
//            if (req.getMenuId() == null) {
//                throw new BusinessException(SystemError.SYSTEM_2106);
//            }
//            Result<List<Long>> permissionResult = sysPermissionService.queryPermission(req.getMenuId(), tokenUser.getId());
//            if (!permissionResult.isSuccess()) {
//                SystemError result = SystemError.getDefined(permissionResult.getCode());
//                throw new BusinessException(result);
//            }
//            data.addAll(permissionResult.getData()) ;
//        }
        IPage<ShipProductPageDTO> agentPage = new Page<>(req.getPageNo(), req.getPageSize());
        agentPage = shipProductSaleStrategyMapper.queryList(req, agentPage,data);
        PageResponse<ShipProductPageDTO> result = new PageResponse<>(agentPage.getRecords(), agentPage.getCurrent() == 1,
                agentPage.getTotal() <= (agentPage.getCurrent() * agentPage.getSize()),
                agentPage.getTotal(), agentPage.getCurrent(), agentPage.getSize());
        return result;
    }

    /**
     * 船票产品上架加幅设置
     *
     * @param reqList
     * @param user
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result saveShipProductSaleStrategy(List<ShipProductSaleStrategyReq> reqList, TokenUser user) {

        Result checkResult = checkProductStrategyReq(reqList, user);
        if (!Objects.isNull(checkResult)) {
            return checkResult;
        }
        Result result = checkStrategyDateResult(reqList);
        if (!Objects.isNull(result)) {
            return result;
        }

        //先查询产品加幅表 存在则修改 不存在则新增  (产品加幅策略对应同一个产品)
        List<ShipProductSaleStrategy> ShipProductSaleStrategyList = shipProductSaleStrategyMapper.
                selectList(new QueryWrapper<ShipProductSaleStrategy>().lambda().eq(ShipProductSaleStrategy::getProductId, reqList.get(0).getProductId()));

        if (CollectionUtils.isEmpty(ShipProductSaleStrategyList)) {

            ShipProduct shipProduct = shipProductMapper.selectById(reqList.get(0).getProductId());
            if (Objects.isNull(shipProduct)) {
                return Result.failed(SystemError.SHIP_PRODUCT_11006);
            }

            if (!ShipConstants.APPROVED.equals(shipProduct.getApprovalStatus())) {
                return Result.failed(SystemError.SHIP_PRODUCT_11022);

            }

            //上架
            shipProduct.setShelvesStatus(ShipConstants.SHELVES);
            shipProductMapper.updateById(shipProduct);

            addShipProductSaleStrategyInfo(reqList, user, reqList.get(0).getProductId());
        } else {
            //修改
            updateShipProductSaleStrategyInfo(reqList, user);
        }

        return Result.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result batchSaveShipProductSaleStrategy(List<ShipProductSaleStrategyReq> reqList, TokenUser user) {
        boolean flag = false;
        Result checkResult = checkProductStrategyReq(reqList, user);
        if (!Objects.isNull(checkResult)) {
            return checkResult;
        }

        Result result = checkStrategyDateResult(reqList);
        if (!Objects.isNull(result)) {
            return result;
        }

        List<Long> productIdList = reqList.get(0).getShipProductIdList();

        if (CollectionUtils.isEmpty(productIdList)) {
            return Result.failed(SystemError.SHIP_PRODUCT_11023);
        }

        //多个产品设置
        for (Long productId : productIdList) {
            ShipProduct shipProduct = shipProductMapper.selectById(productId);
            //上架代码
//            shipProduct.setOnShelfStatus(Constants.SHELVES);
            shipProductMapper.updateById(shipProduct);

            if (!flag) {
                flag = deleteShipProductSaleStrategyInfo(productId);
            }
            addShipProductSaleStrategyInfo(reqList, user, productId);

        }
        return Result.success();
    }


    /**
     * 修改产品加幅信息
     */
    private void updateShipProductSaleStrategyInfo(List<ShipProductSaleStrategyReq> reqList, TokenUser user) {
        boolean flag = false;
        //一个产品加幅策略存在多个
        for (ShipProductSaleStrategyReq req : reqList) {
            //产品加幅表
            ShipProductSaleStrategy shipProductSaleStrategy = new ShipProductSaleStrategy();
            BeanUtils.copyProperties(req, shipProductSaleStrategy);
            shipProductSaleStrategy.setModifiedId(user.getId());
            shipProductSaleStrategy.setGmtModified(LocalDateTime.now());
            shipProductSaleStrategyMapper.updateById(shipProductSaleStrategy);
            List<ShipProductSaleStrategyVaildDateReq> dateReqList = req.getShipProductSaleStrategyVaildDateList();
            //产品加幅日期
            for (ShipProductSaleStrategyVaildDateReq dateReq : dateReqList) {
                ShipProductSaleStrategyVaildDate busProductStrategyDate = new ShipProductSaleStrategyVaildDate();
                BeanUtils.copyProperties(dateReq, busProductStrategyDate);
                busProductStrategyDate.setModifiedId(user.getId());
                busProductStrategyDate.setGmtModified(LocalDateTime.now());
                shipProductSaleStrategyVaildDateMapper.updateById(busProductStrategyDate);
            }
            if (!flag) {
                flag = deleteShipProductSaleStrategyInfo(req.getProductId());
            }
            this.addIncreaseStrategy(req, user, req.getProductId(), req.getId());
        }
    }

    private boolean deleteShipProductSaleStrategyInfo(Long productId) {
        shipProductChannelOfflineMapper.delete(new QueryWrapper<ShipProductChannelOffline>().lambda().eq(ShipProductChannelOffline::getProductId, productId));
        shipProductChannelOfflineAgentCustomMapper.delete(new QueryWrapper<ShipProductChannelOfflineAgentCustom>().lambda().eq(ShipProductChannelOfflineAgentCustom::getProductId, productId));
        shipProductChannelOfflineSelfCustomMapper.delete(new QueryWrapper<ShipProductChannelOfflineSelfCustom>().lambda().eq(ShipProductChannelOfflineSelfCustom::getProductId, productId));
        shipProductChannelOnlineSelfPlatformMapper.delete(new QueryWrapper<ShipProductChannelOnlineSelfPlatform>().lambda().eq(ShipProductChannelOnlineSelfPlatform::getProductId, productId));
        shipProductChannelOnlineThirdPlatformMapper.delete(new QueryWrapper<ShipProductChannelOnlineThirdPlatform>().lambda().eq(ShipProductChannelOnlineThirdPlatform::getProductId, productId));
        return true;
    }


    /**
     * 加幅渠道和加幅时间校验
     *
     * @param shipProductStrategyReqList
     * @return
     */
    private Result<Object> checkStrategyDateResult(List<ShipProductSaleStrategyReq> shipProductStrategyReqList) {

        List<ShipProductSaleStrategyVaildDateReq> shipProductStrategyDateReqList = new ArrayList<>();
        // 四种渠道至少有一个在售校验
        for (ShipProductSaleStrategyReq shipProductStrategyReq : shipProductStrategyReqList) {
            shipProductStrategyDateReqList.addAll(shipProductStrategyReq.getShipProductSaleStrategyVaildDateList());
            // 线下-自营渠道
            if (shipProductStrategyReq.getSelfSalePermissionType() == ShipConstants.SALE_CHANNEL_TYPE_ALL) {
                continue;
            }
            if (shipProductStrategyReq.getSelfSalePermissionType() == ShipConstants.SALE_CHANNEL_TYPE_SELECTED && com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isNotEmpty(shipProductStrategyReq.getShipProductChannelOfflineSelfCustomList())) {
                continue;
            }
            // 线下-代理渠道
            if (shipProductStrategyReq.getAgentSalePermissionType() == ShipConstants.SALE_CHANNEL_TYPE_ALL) {
                continue;
            }
            if (shipProductStrategyReq.getAgentSalePermissionType() == ShipConstants.SALE_CHANNEL_TYPE_SELECTED && com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isNotEmpty(shipProductStrategyReq.getShipProductChannelOfflineAgentCustomList())) {
                continue;
            }
            //线上-自营渠道
            if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isNotEmpty(shipProductStrategyReq.getShipProductChannelOnlineSelfPlatformList())) {
                continue;
            }
            //线上-第三方渠道
            if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isNotEmpty(shipProductStrategyReq.getShipProductChannelOnlineThirdPlatformList())) {
                continue;
            }
            return Result.failed(SystemError.SHIP_PRODUCT_11018);
        }
        for (int i = 0; i < shipProductStrategyDateReqList.size(); i++) {
            ShipProductSaleStrategyVaildDateReq shipProductStrategyDateReq = shipProductStrategyDateReqList.get(i);
            if (shipProductStrategyDateReq.getTimeBegin().isBefore(LocalDate.now())) {
                // 船票产品加幅策略保存，开始日期不能小于当前日期校验
                return Result.failed(SystemError.SHIP_PRODUCT_11019);
            }
            if (i == 0 && shipProductStrategyDateReq.getTimeBegin().isAfter(shipProductStrategyDateReq.getTimeEnd())) {
                // 开始日期必须小于结束日期校验
                return Result.failed(SystemError.SHIP_PRODUCT_11020);
            }
            for (int j = 0; j < shipProductStrategyDateReqList.size(); j++) {
                ShipProductSaleStrategyVaildDateReq strategyDateReqTemp = shipProductStrategyDateReqList.get(j);
                if (i >= j) { // 自身和已经校验过的跳过日期校验
                    continue;
                }
                if (i == 0 && strategyDateReqTemp.getTimeBegin().isAfter(strategyDateReqTemp.getTimeEnd())) {
                    // 开始日期必须小于结束日期校验
                    return Result.failed(SystemError.SHIP_PRODUCT_11019);
                }
                if (DateUtil.isDateRange(shipProductStrategyDateReq.getTimeBegin(), shipProductStrategyDateReq.getTimeEnd(), strategyDateReqTemp.getTimeBegin(), strategyDateReqTemp.getTimeEnd())) {
                    // 当前日期与其他日期区域重叠校验
                    return Result.failed(SystemError.SHIP_PRODUCT_11021);
                }
            }
        }
        return null;
    }

    /**
     * 校验产品加幅信息入参
     *
     * @param reqList
     * @param user
     * @return
     */
    private Result checkProductStrategyReq(List<ShipProductSaleStrategyReq> reqList, TokenUser user) {
        if (Objects.isNull(user)) {
            return Result.failed(SystemError.USER_1000);
        }
        if (CollectionUtils.isEmpty(reqList)) {
            return Result.failed(SystemError.SHIP_PRODUCT_11016);
        }
        return null;
    }

    /**
     * 新增产品加幅信息
     *
     * @param reqList
     * @param user
     * @param productId
     */
    private void addShipProductSaleStrategyInfo(List<ShipProductSaleStrategyReq> reqList, TokenUser user, Long productId) {

        //一个产品加幅策略存在多个
        for (ShipProductSaleStrategyReq req : reqList) {
            //产品加幅表
            ShipProductSaleStrategy shipProductSaleStrategy = new ShipProductSaleStrategy();
            BeanUtils.copyProperties(req, shipProductSaleStrategy);
            if (productId != null) {
                shipProductSaleStrategy.setProductId(productId);
            }
            Long productStrategyId = SnowflakeIdWorker.nextId();
            shipProductSaleStrategy.setId(productStrategyId);
            shipProductSaleStrategy.setCreateId(user.getId());
            shipProductSaleStrategy.setGmtCreate(LocalDateTime.now());
            shipProductSaleStrategy.setIsDeleted(ShipConstants.NOT_DELETE);
            shipProductSaleStrategyMapper.insert(shipProductSaleStrategy);
            List<ShipProductSaleStrategyVaildDateReq> dateReqList = req.getShipProductSaleStrategyVaildDateList();
            //产品加幅日期
            for (ShipProductSaleStrategyVaildDateReq dateReq : dateReqList) {
                ShipProductSaleStrategyVaildDate busProductStrategyDate = new ShipProductSaleStrategyVaildDate();
                BeanUtils.copyProperties(dateReq, busProductStrategyDate);
                busProductStrategyDate.setId(SnowflakeIdWorker.nextId());
                busProductStrategyDate.setStrategyId(productStrategyId);
                shipProductSaleStrategyVaildDateMapper.insert(busProductStrategyDate);
            }
            this.addIncreaseStrategy(req, user, productId, productStrategyId);
        }
    }

    private void addIncreaseStrategy(ShipProductSaleStrategyReq req, TokenUser user, Long productId, Long productStrategyId) {
        //线下代理商自定义用户部门req
        List<ShipProductChannelOfflineAgentCustomReq> agentCustomReqList = req.getShipProductChannelOfflineAgentCustomList();
        for (ShipProductChannelOfflineAgentCustomReq agentCustomReq : agentCustomReqList) {
            ShipProductChannelOffline agentCustom = new ShipProductChannelOffline();
            BeanUtils.copyProperties(agentCustomReq, agentCustom);
            long agentCustomId = SnowflakeIdWorker.nextId();
            agentCustom.setId(agentCustomId);
            agentCustom.setStrategyId(productStrategyId);
            agentCustom.setCreateId(user.getId());
            agentCustom.setGmtCreate(LocalDateTime.now());
            agentCustom.setIsDeleted(ShipConstants.NOT_DELETE);
            shipProductChannelOfflineMapper.insert(agentCustom);
            //对应的船票产品加幅策略规则
            List<ShipProductChannelOfflineAgentCustomArrayReq> strategyRuleReqList = agentCustomReq.getShipProductChannelOfflineAgentCustomArray();
            for (ShipProductChannelOfflineAgentCustomArrayReq ruleReq : strategyRuleReqList) {
                ShipProductChannelOfflineAgentCustom strategyRule = new ShipProductChannelOfflineAgentCustom();
                BeanUtils.copyProperties(ruleReq, strategyRule);
                strategyRule.setId(SnowflakeIdWorker.nextId());
                strategyRule.setOfflineId(agentCustomId);
                strategyRule.setProductId(productId);
                shipProductChannelOfflineAgentCustomMapper.insert(strategyRule);
            }
        }
        //线下自营自定义用户部门req
        List<ShipProductChannelOfflineSelfCustomReq> selfCustomReqList = req.getShipProductChannelOfflineSelfCustomList();
        for (ShipProductChannelOfflineSelfCustomReq selfCustomReq : selfCustomReqList) {
            ShipProductChannelOffline selfCustom = new ShipProductChannelOffline();
            BeanUtils.copyProperties(selfCustomReq, selfCustom);
            long selfCustomId = SnowflakeIdWorker.nextId();
            selfCustom.setId(selfCustomId);
            selfCustom.setStrategyId(productStrategyId);
            selfCustom.setCreateId(user.getId());
            selfCustom.setGmtCreate(LocalDateTime.now());
            selfCustom.setIsDeleted(ShipConstants.NOT_DELETE);
            shipProductChannelOfflineMapper.insert(selfCustom);
            //对应的船票产品加幅策略规则
            List<ShipProductChannelOfflineSelfCustomArrayReq> strategyRuleReqList = selfCustomReq.getShipProductChannelOfflineSelfCustomArray();
            for (ShipProductChannelOfflineSelfCustomArrayReq ruleReq : strategyRuleReqList) {
                ShipProductChannelOfflineSelfCustom strategyRule = new ShipProductChannelOfflineSelfCustom();
                BeanUtils.copyProperties(ruleReq, strategyRule);
                strategyRule.setId(SnowflakeIdWorker.nextId());
                strategyRule.setOfflineId(selfCustomId);
                strategyRule.setProductId(productId);
                shipProductChannelOfflineSelfCustomMapper.insert(strategyRule);
            }

        }
        //线上渠道自定义权限
        List<ShipProductChannelOnlineSelfPlatformReq> selfPlatformReqList = req.getShipProductChannelOnlineSelfPlatformList();
        for (ShipProductChannelOnlineSelfPlatformReq selfPlatformReq : selfPlatformReqList) {
            ShipProductChannelOnlineSelfPlatform selfPlatform = new ShipProductChannelOnlineSelfPlatform();
            BeanUtils.copyProperties(selfPlatformReq, selfPlatform);
            long selfPlatformId = SnowflakeIdWorker.nextId();
            selfPlatform.setId(selfPlatformId);
            selfPlatform.setProductId(productId);
            selfPlatform.setStrategyId(productStrategyId);
            selfPlatform.setCreateId(user.getId());
            selfPlatform.setGmtCreate(LocalDateTime.now());
            selfPlatform.setIsDeleted(ShipConstants.NOT_DELETE);
            shipProductChannelOnlineSelfPlatformMapper.insert(selfPlatform);
        }
        //线上渠道第三方平台
        List<ShipProductChannelOnlineThirdPlatformReq> thirdPlatformReqList = req.getShipProductChannelOnlineThirdPlatformList();
        for (ShipProductChannelOnlineThirdPlatformReq thirdPlatformReq : thirdPlatformReqList) {
            ShipProductChannelOnlineThirdPlatform thirdPlatform = new ShipProductChannelOnlineThirdPlatform();
            BeanUtils.copyProperties(thirdPlatformReq, thirdPlatform);
            long thirdPlatformId = SnowflakeIdWorker.nextId();
            thirdPlatform.setId(thirdPlatformId);
            thirdPlatform.setStrategyId(productStrategyId);
            thirdPlatform.setProductId(productId);
            thirdPlatform.setCreateId(user.getId());
            thirdPlatform.setGmtCreate(LocalDateTime.now());
            thirdPlatform.setIsDeleted(ShipConstants.NOT_DELETE);
            shipProductChannelOnlineThirdPlatformMapper.insert(thirdPlatform);
        }
    }
}
